
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using igather.Search.FlickrSearchEngine;
using igather.Framework;
using igather.Framework.Clustering;
using igather.Clustering;
using igather.Clustering.MCL;
using FlickrNet;
namespace IGatherWebGUI
{

	public partial class Search : System.Web.UI.Page
	{
		private const int RESULTS = 100;
		private const int EXPANSION_POWER = 2;
		private const double INFLATION_POWER = 1.5;
		private const int LOOPS = 500;
		private const double PRECISION = 0.001;
		private const double PRUNE = 0.001;
		
		private class ClusterComparer : IComparer<Cluster>
		{
			public int Compare (Cluster x, Cluster y)
			{
				Metrics metrics1 = x.GetMetrics();
				Metrics metrics2 = y.GetMetrics();
				return (metrics2.Cohesion-metrics2.Separation).CompareTo((metrics1.Cohesion-metrics1.Separation));
			}
		}
		
		public virtual void searchButtonClicked(object sender, EventArgs args)
		{
			Response.Redirect(string.Format("Search.aspx?q={0}", Server.UrlEncode(searchBox.Text.Replace(' ',','))));
		}
		
		public virtual void onLoad(object sender, EventArgs args)
		{
			if (!IsPostBack)
			{
				string tags = Server.UrlDecode(Request.QueryString["q"]);
				searchBox.Text = tags;
				int page = Convert.ToInt32(Request.QueryString["p"] ?? "0");
				nextPage.NavigateUrl = string.Format("Search.aspx?q={0}&p={1}", tags, ++page);
				if (!string.IsNullOrEmpty(tags))
				{
					FlickrSearchEngine searchEngine = new FlickrSearchEngine();
					IGraph graph = searchEngine.Search(tags, RESULTS, page);
					MCL mcl = new MCL();
					mcl.ExpansionPower = EXPANSION_POWER;
					mcl.InflationPower = INFLATION_POWER;
					mcl.Loops = LOOPS;
					mcl.Precision = PRECISION;
					mcl.Prune = PRUNE;
					IClusteringEngine clusteringEngine = (IClusteringEngine)mcl;
					ClusteredGraph clusteredGraph = clusteringEngine.GetClusters(graph);
					clusteredGraph.Clusters.Sort(new ClusterComparer());
					
					tagsLabel.Text = tags;
					if (clusteredGraph.Clusters.Count > 0)
					{
						string clusterName = clusteredGraph.Clusters[0].GetRepresentativeVertexByConectivitie().Name;
						List<string> thumbs = searchEngine.SearchThumbs(string.Format("{0},{1}", tags, clusterName));
						if (thumbs.Count >= 4)
						{
							tag1Label.Text = clusterName;
							tag1Label.NavigateUrl = string.Format("Search.aspx?q={0},{1}", tags, clusterName);
							tag1Img1.Visible = tag1Img2.Visible = tag1Img3.Visible = tag1Img4.Visible = true;
							tag1Img1.ImageUrl = thumbs[0];
							tag1Img2.ImageUrl = thumbs[1];
							tag1Img3.ImageUrl = thumbs[2];
							tag1Img4.ImageUrl = thumbs[3];
						}
					}
					if (clusteredGraph.Clusters.Count > 1)
					{
						string clusterName = clusteredGraph.Clusters[1].GetRepresentativeVertexByConectivitie().Name;
						List<string> thumbs = searchEngine.SearchThumbs(string.Format("{0},{1}", tags, clusterName));
						if (thumbs.Count >= 4)
						{
							tag2Label.Text = clusterName;
							tag2Label.NavigateUrl = string.Format("Search.aspx?q={0},{1}", tags, clusterName);
							tag2Img1.Visible = tag2Img2.Visible = tag2Img3.Visible = tag2Img4.Visible = true;
							tag2Img1.ImageUrl = thumbs[0];
							tag2Img2.ImageUrl = thumbs[1];
							tag2Img3.ImageUrl = thumbs[2];
							tag2Img4.ImageUrl = thumbs[3];
						}
					}
					if (clusteredGraph.Clusters.Count > 2)
					{
						string clusterName = clusteredGraph.Clusters[2].GetRepresentativeVertexByConectivitie().Name;
						List<string> thumbs = searchEngine.SearchThumbs(string.Format("{0},{1}", tags, clusterName));
						if (thumbs.Count >= 4)
						{
							tag3Label.Text = clusterName;
							tag3Label.NavigateUrl = string.Format("Search.aspx?q={0},{1}", tags, clusterName);
							tag3Img1.Visible = tag3Img2.Visible = tag3Img3.Visible = tag3Img4.Visible = true;
							tag3Img1.ImageUrl = thumbs[0];
							tag3Img2.ImageUrl = thumbs[1];
							tag3Img3.ImageUrl = thumbs[2];
							tag3Img4.ImageUrl = thumbs[3];
						}
					}
					if (clusteredGraph.Clusters.Count > 3)
					{
						string clusterName = clusteredGraph.Clusters[3].GetRepresentativeVertexByConectivitie().Name;
						List<string> thumbs = searchEngine.SearchThumbs(string.Format("{0},{1}", tags, clusterName));
						if (thumbs.Count >= 4)
						{
							tag4Label.Text = clusterName;
							tag4Label.NavigateUrl = string.Format("Search.aspx?q={0},{1}", tags, clusterName);
							tag4Img1.Visible = tag4Img2.Visible = tag4Img3.Visible = tag4Img4.Visible = true;
							tag4Img1.ImageUrl = thumbs[0];
							tag4Img2.ImageUrl = thumbs[1];
							tag4Img3.ImageUrl = thumbs[2];
							tag4Img4.ImageUrl = thumbs[3];
						}
					}
					
					//Regular results
					resultNumbers.Text = string.Format("Results <b>{0}</b> - <b>{1}</b> of <b>{2}</b> for <b>{3}</b>", 
						((searchEngine.FlickrRawResults.PageNumber-1) * searchEngine.FlickrRawResults.PhotosPerPage) + 1,
					    (searchEngine.FlickrRawResults.PageNumber * searchEngine.FlickrRawResults.PhotosPerPage),
					    searchEngine.FlickrRawResults.TotalPhotos,
						tags);
					foreach (Photo p in searchEngine.FlickrRawResults.PhotoCollection)
					{
						HyperLink thumb = new HyperLink();
						thumb.Attributes["class"] = "thumb";
						thumb.ImageUrl = p.SquareThumbnailUrl;
						thumb.NavigateUrl = p.WebUrl;
						HyperLink title = new HyperLink();
						title.Attributes["class"] = "title";
						title.Text = p.Title + "<br />";
						Label desc = new Label();
						desc.Attributes["class"] = "desc";
						desc.Text = p.OwnerName + "<br />" + p.DateUploaded + "<br /><br />";
						searchResults.Controls.Add(thumb);
						searchResults.Controls.Add(title);
						searchResults.Controls.Add(desc);
					}
				}
			}
		}
	}
}
